<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script>
      /*
            给定一个字符串 s ，请你找出其中不含有重复字符的 最长 子串 的长度。 

            示例 1:

            输入: s = "abcabcbb"
            输出: 3 
            解释: 因为无重复字符的最长子串是 "abc"，所以其长度为 3。
            示例 2:

            输入: s = "bbbbb"
            输出: 1
            解释: 因为无重复字符的最长子串是 "b"，所以其长度为 1。
            示例 3:

            输入: s = "pwwkew"
            输出: 3
            解释: 因为无重复字符的最长子串是 "wke"，所以其长度为 3。
                请注意，你的答案必须是 子串 的长度，"pwke" 是一个子序列，不是子串。       
        
        */
      /**
       * @param {string} s
       * @return {number}
       */
      function lengthOfLongestSubstring(s) {
        /**
         * 思路：双指针 - 滑动窗口
         * 1. 左右指针都在最左侧
         * 2. 右指针逐步向右移动
         * 3. 每次移动看下是否有重复字符
         * 4. 如有重复字符，则说明这是一次结果，可记录下来，与上一次结果比较
         * 5. 左指针逐步向右移动，移动一次则需要从Set中删除掉左指针前一个字符
         * 6. 重复2-5步，直到右指针到达最右侧
         * **/
        const occ = new Set();
        const len = s.length;
        let rk = 0; // 右指针
        let ans = 0; // 结果长度
        // i => 左指针
        for (let i = 0; i < len; i++) {
          if (i != 0) {
            occ.delete(s.charAt(i - 1));
          }
          while (rk < len && !occ.has(s.charAt(rk))) {
            occ.add(s.charAt(rk));
            rk++;
          }
          ans = Math.max(ans, rk - i);
        }
        return ans;
      }

      console.log(lengthOfLongestSubstring("pwwkew"));
      console.log(lengthOfLongestSubstring("abba"));
      console.log(lengthOfLongestSubstring("au"));
      console.log(lengthOfLongestSubstring(" "));
    </script>
  </body>
</html>
